#include "OGLWindow.h"

#include "player.h"
#include "camera.h"
#include "world.h"
#include "DirectXAudio.h"

// disable implicit float-double casting
#pragma warning(disable:4305)

OGLWindow::OGLWindow() {}

OGLWindow::~OGLWindow() {}

bool OGLWindow::Init()
{   
    // clear to black background
    glClearColor(0.0, 0.0, 0.0, 0.0);
	mouseSensitivity = 1.0f;
    m_angle = 0.0f;
	gameCamera = new CCamera;
	gameWorld = new CWorld(gameCamera);
	
	// Ian Bell - 12/4/2012
	// "Fixes" bug where game initially moves camera forward and to the right
	OnKeyDown(0x53);
	OnKeyDown(0x41);

	OnKeyUp(0x53);
	OnKeyUp(0x41);

    return true;
}

bool OGLWindow::Shutdown()
{
	delete gameWorld;
	delete gameCamera;
	gameWorld = NULL;
	gameCamera = NULL;
    return true;
}


CCamera* OGLWindow::OnGetCamera()
{
	return gameCamera;
}

CWorld* OGLWindow::OnGetWorld()
{
	return gameWorld;
}


void OGLWindow::SetupProjection(int width, int height)
{
    if (height == 0)                    // don't want a divide by zero
    {
        height = 1;                 
    }

    glViewport(0, 0, width, height);        // reset the viewport to new dimensions
    glMatrixMode(GL_PROJECTION);            // set projection matrix current matrix
    glLoadIdentity();                       // reset projection matrix

    // calculate aspect ratio of window
    gluPerspective(52.0f,(GLfloat)width/(GLfloat)height,1.0f,1000.0f);

    glMatrixMode(GL_MODELVIEW);             // set modelview matrix
    glLoadIdentity();                       // reset modelview matrix

    m_windowWidth = width;
    m_windowHeight = height;
}
void OGLWindow::Prepare()
{
	// clear screen and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     
//	glMatrixMode(GL_MODELVIEW); 
	glLoadIdentity();
    m_angle += 0.1f;
}
// GetMouseX()
// desc: get mouse cursor position in window
int OGLWindow::GetMouseX(LPARAM lParam)
{
	return LOWORD(lParam);
}

// GetMouseY()
// desc: get mouse cursor position in window
int OGLWindow::GetMouseY(LPARAM lParam)
{
	return HIWORD(lParam);
}

static int oldX = 0;
static int oldY = 0;
static bool b = false;

void OGLWindow::OnMouseMove(int x, int y)
{
	b = !b;
	if(b)
	{
		int dx = oldX - x;
		int dy = oldY - y;

		gameCamera->yaw += (-dx * mouseSensitivity) / 4;
		gameCamera->pitch += (dy * mouseSensitivity) / 4;

		SetCursorPos(this->m_windowWidth / 2, this->m_windowHeight / 2);
	}

	oldX = x;
	oldY = y;
}

void OGLWindow::endGameLogic()
{
	CObject* heli = (CObject*)(gameWorld->heli);

	double dist = gameWorld->player->DistanceToObject(heli);

	if (dist <= 30.0)
	{
		gameWorld->SetGameDone(true);
	}
	else
	{
		CDirectXAudio * audioSys = new CDirectXAudio;

		audioSys->PlaySoundDX(audioSys->iGetToThaChoppa); // Get to tha choppa!
	}
}

void OGLWindow::OnKeyDown(int nVirtKey)
{
	if (!gameWorld->IsGameDone())
	{
		switch (nVirtKey)
		{
		case 0x48: // h
			endGameLogic();
			break;
		case 0x57: // w
			gameCamera->moveForward = true;
			gameCamera->moveBackward = false;
			break;
		case 0x53: // s
			gameCamera->moveForward = false;
			gameCamera->moveBackward = true;
			break;
		case 0x44: // d
			gameCamera->moveRightward = true;
			gameCamera->moveLeftward = false;
			break;
		case 0x41: // a
			gameCamera->moveRightward = false;
			gameCamera->moveLeftward = true;
			break;
		case 0x57 + 0x44: // w + d
			gameCamera->moveForward = true;
			gameCamera->moveBackward = false;
			gameCamera->moveRightward = true;
			gameCamera->moveLeftward = false;
			break;
		case 0x57 + 0x41: // w + a
			gameCamera->moveForward = true;
			gameCamera->moveBackward = false;
			gameCamera->moveRightward = false;
			gameCamera->moveLeftward = true;
			break;
		case 0x53 + 0x44: // s + d
			gameCamera->moveForward = false;
			gameCamera->moveBackward = true;
			gameCamera->moveRightward = true;
			gameCamera->moveLeftward = false;
			break;
		case 0x53 + 0x41: // s + a
			gameCamera->moveForward = false;
			gameCamera->moveBackward = true;
			gameCamera->moveRightward = false;
			gameCamera->moveLeftward = true;
			break;
		case VK_ADD:
			mouseSensitivity += 0.1f;
			break;
		case VK_SUBTRACT:
			mouseSensitivity -= 0.1f;
			if (mouseSensitivity < 0.1)
				mouseSensitivity = 0.1;
			break;
		default:
			break;
		}
	}
	else
	{
		gameCamera->moveForward = false;
		gameCamera->moveBackward = false;
		gameCamera->moveRightward = false;
		gameCamera->moveLeftward = false;
	}
}

// Ian Bell - 12/3/2012
void OGLWindow::OnKeyUp(int nVirtKey)
{
	if (!gameWorld->IsGameDone())
	{
		switch (nVirtKey)
		{
		case 0x57: // w
			gameCamera->moveForward = false;
			break;
		case 0x53: // s
			gameCamera->moveBackward = false;
			break;
		case 0x44: // d
			gameCamera->moveRightward = false;
			break;
		case 0x41: // a
			gameCamera->moveLeftward = false;
			break;
		default:
			break;
		}

	}
}

void OGLWindow::OnMouseDownL(int x, int y) 
{
	if (!gameWorld->IsGameDone())
		gameWorld->player->StartWeapon();
}

void OGLWindow::OnMouseUpL(int x, int y) 
{
	if (!gameWorld->IsGameDone())
		gameWorld->player->EndWeapon();
}

void OGLWindow::OnMouseDownR(int x, int y)
{
	if (!gameWorld->IsGameDone())
		gameWorld->player->LaunchSnowBall();
}

void OGLWindow::Render(float deltaTime)
{
	CCamera *camera = OnGetCamera();
	CWorld *world = OnGetWorld();

	world->Prepare();
	camera->Animate(deltaTime);
	world->Animate(deltaTime);
	world->Draw(camera);
	world->Draw2D(m_windowWidth, m_windowHeight);
}